import { Mesh } from "three";
import { MergeMeshCommand } from "./commands/MergeObjectCommand";
import { RemoveObjectCommand } from "./commands/RemoveObjectCommand";
import { Editor } from "./editor";
import { SimplifyModifier } from 'three/examples/jsm/modifiers/SimplifyModifier'
import { SetGeometryCommand } from "./commands/SetGeometryCommand";


const IS_MAC = /macintosh|mac os x/i.test(navigator.userAgent);

/**
 * @return void 或 true 阻止默认事件
 */
type KeyHandlerFn=(event:KeyboardEvent)=>boolean|void;

export class Keyboard{
  editor:Editor;
  dom:Document|HTMLElement;
  pause:boolean=false;
  classNameEffect:string[]=['tezero-viewport','tezero-outliner'];

  keyMap:Map<string,KeyHandlerFn> = new Map([
    ['MOD-C',(event:KeyboardEvent)=>{
      this.editor.copy();
    }],
    ['MOD-V', (event:KeyboardEvent)=>{
      this.editor.paste();
    }],
    ['MOD-Z', (event:KeyboardEvent)=>{
      this.editor.undo();
    }],
    ['MOD-Y', (event:KeyboardEvent)=>{
      this.editor.redo();
    }],
    ['H',(event:KeyboardEvent)=>{
      const object=this.editor.selected;
      if(object&&object instanceof Mesh){
        const modifier = new SimplifyModifier();
        const count = Math.floor( object.geometry.attributes.position.count * 0.875 ); // 需要移除模型点数的百分比
        const geometry = modifier.modify( object.geometry, count );
        this.editor.execute(new SetGeometryCommand(this.editor,object,geometry));

        
      }
      return true;
    }],
    ['T',(event:KeyboardEvent)=>{
      this.editor.signals.transformModeChanged.dispatch('translate');
      return true;
    }],
    ['R',(event:KeyboardEvent)=>{
      this.editor.signals.transformModeChanged.dispatch('rotate');
      return true;
    }],
    ['S',(event:KeyboardEvent)=>{
      this.editor.signals.transformModeChanged.dispatch('scale');
      return true;
    }],
    ['M',(event:KeyboardEvent)=>{
      if(this.editor.selected){
        const children=this.editor.selected.children;
        if(children.length>=2){
          this.editor.execute(new MergeMeshCommand(this.editor,children[0] as Mesh,children[1] as Mesh));
        }
      }
      return true;
    }],
    ['DELETE', (event:KeyboardEvent)=>{
      if(this.editor.selected){
        this.editor.execute( new RemoveObjectCommand( this.editor, this.editor.selected ) );
      }
      return true;
    }],
    ['BACKSPACE', (event:KeyboardEvent)=>{
      if(this.editor.selected){
        this.editor.execute( new RemoveObjectCommand( this.editor, this.editor.selected ) );
      }
      return true;
    }],
  ]);

  constructor( editor:Editor,dom:HTMLElement|Document=document ) {
    this.editor=editor;
    this.dom=dom;
    this.listen();
  }

  public key(key:string,handler:KeyHandlerFn){
    if(this.keyMap.has(key)){
      throw new Error(`快捷键[${key}]冲突`);
    }
    this.keyMap.set(key,handler);
  }

  public isEffect(event:KeyboardEvent){
    if(event.target){
      const target=event.target as HTMLElement;
      for(let i=0;i<this.classNameEffect.length;i++){
        if(target.classList.contains(this.classNameEffect[i])){
          return true;
        }
      }
      
    }
    return false;
  }

  private onKeydown(event:KeyboardEvent) {
    // console.log(event);
    // 获取按下的键名
    if(this.pause)return;
    if(!this.isEffect(event))return;
    const key = this.getKey(event);
    // 检查是否按下了组合按键
    if (event.shiftKey || event.ctrlKey) {
      // 组合按键格式：ModifierKey-Key
      const combinationKey = `${this.getModifierKey(event)}-${key}`;
      // 查找并执行组合按键对应的操作
      if (this.keyMap.has(combinationKey)) {
        const operation = this.keyMap.get(combinationKey);
        if(operation){
          const prevent=operation(event);
          if(prevent===undefined||prevent===true)
          event.preventDefault();
        }
        
      }
    } else {
      // 查找并执行按键对应的操作
      if (this.keyMap.has(key)) {
        const operation = this.keyMap.get(key);
        if(operation){
          const prevent=operation(event);
          if(prevent===undefined||prevent===true)
          event.preventDefault();
        }
        
      }
    }
  }

  listen(){
    // 监听键盘按下事件
    // this.dom.addEventListener('keydown', this.onKeydown.bind(this));
    this.dom.addEventListener('keydown', this.onKeydown.bind(this));
  }

  // 辅助函数，获取按下的键名
  getKey(event:KeyboardEvent) {
    // 使用event.key获取按下的键名
    return event.key.toUpperCase();
  }

  // 辅助函数，获取组合按键中的修饰键
  getModifierKey(event:KeyboardEvent) {
    const modifierKeys = [];

    // 检查Mac系统的cmd键或其他系统的Ctrl键
    if((IS_MAC&&event.metaKey)||event.ctrlKey){
      modifierKeys.push('MOD');
    }

    // 检查Shift键
    if (event.shiftKey) {
      modifierKeys.push('SHIFT');
    }

    return modifierKeys.join('-');
  }

  destroy(){
    this.dom.removeEventListener('keydown',this.onKeydown);
  }

}